﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Runtime.Serialization;

namespace NetTcpServer {
    
    public class TestData {
        public string Data { get; set; }
        public int Value { get; set; }
        public TestComplex Complex { get; set; }
    }

    public class TestComplex {
        public string ComplexData { get; set; }
        public List<ArrayData> Values { get; set; }
        public TestComplexInner Inner { get; set; }
    }

    public class ArrayData {
        public int Value { get; set; }
        public override string ToString() {
            return Value.ToString();
        }
    }

    public class TestComplexInner {
        public string ComplexInnerData { get; set; }
        public Dictionary<string, ArrayData> ComplexInnerDict { get; set; }
    }

    [ServiceContract]
    public interface INetTcpServer {
        [OperationContract]
        void TestMethod(TestData value, string value2, Dictionary<string, ArrayData> list);
    }

    public class NetTcpService : INetTcpServer {
        public void TestMethod(TestData value, string value2, Dictionary<string, ArrayData> list) {
            Console.WriteLine("Got Message: {0} {1} {2} {3} {4} {5} {6} {7}", value.Data,
                value2, value.Value, value.Complex.ComplexData, value.Complex.Inner.ComplexInnerData,
                 String.Join(" ", value.Complex.Values.Select(v => v.Value)),
                 String.Join(" ", value.Complex.Inner.ComplexInnerDict
                 .Select(kv => String.Format("Key: {0}, Value: {1}", kv.Key, kv.Value.Value))),
                 String.Join(" ", list));
        }
    }
    class Program {
        static void Main(string[] args) {
            var mexBinding = MetadataExchangeBindings.CreateMexHttpBinding();


            var netTcpBinding = new NetTcpBinding(SecurityMode.None)
            {
                MaxBufferSize = Int32.MaxValue,
                MaxReceivedMessageSize = Int32.MaxValue,
                TransferMode = TransferMode.Streamed
            };

            netTcpBinding.ReaderQuotas.MaxBytesPerRead = Int32.MaxValue;
            netTcpBinding.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
            netTcpBinding.ReaderQuotas.MaxNameTableCharCount = Int32.MaxValue;
            netTcpBinding.ReaderQuotas.MaxDepth = Int32.MaxValue;



            var serviceHost = new ServiceHost(typeof(NetTcpService),
                new Uri("net.tcp://localhost:1234/NetTcpService"),
                new Uri("http://localhost:1235/TestNetTcp"));

            serviceHost.Description.Behaviors.Add(new System.ServiceModel.Description.ServiceMetadataBehavior() { HttpGetEnabled = true });


            serviceHost.AddServiceEndpoint(typeof(INetTcpServer), netTcpBinding, String.Empty);
            serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, "mex");

            serviceHost.Open();
            Console.WriteLine("Waiting for connections...... Press enter to exit");
            Console.ReadLine();
        }
    }
}
